<template>
  <div class="table-box">
    <el-table
      ref="mytableRef"
      :data="tableData"
      stripe
      max-height="59vh"
      :header-cell-style="{ color: '#fff', backgroundColor: '#4977af' }"
      :row-style="{ height: '80px' }"
      @select="handleSelectionChange"
      @select-all="handleSelectionChange"
      class="mytable"
    >
      <el-table-column type="selection" width="50" align="center" />
      <el-table-column
        type="index"
        :index="indexMethod"
        label="序号"
        width="60"
        align="center"
      />

      <el-table-column label="姓名" align="center">
        <template #default="scope">
          <el-input
            v-if="isEditing[scope.$index].memberName"
            v-model="scope.row.memberName"
            @blur="changeStatus(scope.$index, 'memberName')"
            v-focus
          />

          <p v-else @dblclick="changeStatus(scope.$index, 'memberName')">
            {{ scope.row.memberName }}
          </p>
        </template>
      </el-table-column>

      <el-table-column label="性别" align="center">
        <template #default="scope">
          <el-select
            v-if="isSelecting[scope.$index].sex"
            v-model="scope.row.sex"
            @visible-change="
              handleVisibleChange($event, scope.$index, 'sex', true)
            "
            v-selectClick
          >
            <el-option
              v-for="item in options['性别']"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>

          <p v-else @dblclick="changeStatus(scope.$index, 'sex', true)">
            {{ scope.row.sex }}
          </p>
        </template>
      </el-table-column>

      <el-table-column label="学号" align="center">
        <template #default="scope">
          <el-input
            v-if="isEditing[scope.$index].studentID"
            v-model="scope.row.studentID"
            @blur="changeStatus(scope.$index, 'studentID')"
            v-focus
          />

          <p v-else @dblclick="changeStatus(scope.$index, 'studentID')">
            {{ scope.row.studentID }}
          </p>
        </template>
      </el-table-column>

      <el-table-column label="学院" align="center">
        <template #default="scope">
          <el-input
            v-if="isEditing[scope.$index].college"
            v-model="scope.row.college"
            @blur="changeStatus(scope.$index, 'college')"
            v-focus
          />

          <p v-else @dblclick="changeStatus(scope.$index, 'college')">
            {{ scope.row.college }}
          </p>
        </template>
      </el-table-column>

      <el-table-column label="加入时间" align="center">
        <template #default="scope">
          <el-input
            v-if="isEditing[scope.$index].joinTime"
            v-model="scope.row.joinTime"
            @blur="changeStatus(scope.$index, 'joinTime')"
            v-focus
          />

          <p v-else @dblclick="changeStatus(scope.$index, 'joinTime')">
            {{ scope.row.joinTime }}
          </p>
        </template>
      </el-table-column>

      <el-table-column label="联系电话" align="center">
        <template #default="scope">
          <el-input
            v-if="isEditing[scope.$index].phone"
            v-model="scope.row.phone"
            @blur="changeStatus(scope.$index, 'phone')"
            v-focus
          />

          <p v-else @dblclick="changeStatus(scope.$index, 'phone')">
            {{ scope.row.phone }}
          </p>
        </template>
      </el-table-column>

      <el-table-column label="所在社团及职位" align="center">
        <template #default="scope">
          <p
            :title="computePosition(scope.$index)"
            v-if="store.getters.organizationMap"
          >
            {{ computePosition(scope.$index) }}
          </p>
        </template>
      </el-table-column>

      <el-table-column fixed="right" label="操作" width="120" align="center">
        <template #default="scope">
          <div class="operation">
            <span @click="handleEdit(scope.$index, scope.row)">编辑</span>
            <span class="delete" @click="handleDelete(scope.$index, scope.row)"
              >删除</span
            >
          </div>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script lang="ts">
export default {
  directives: {
    selectClick: {
      mounted: (el) => {
        el.querySelector("input").click();
      },
    },
  },
};
</script>

<script lang="ts" setup>
import { computed, reactive, watchEffect, watch, ref, toRefs } from "vue";
import { ElMessage, ElTable } from "element-plus";
import lodash from "lodash";
import { useStore } from "vuex";

import { selects, options } from "@/data/select.ts";
import { organizationMemberMap } from "@/data/tableMap.ts";

import isDateValid from "@/utils/isDateValid.ts";

interface ITable {
  [key: string]: any;
}

const props = defineProps(["tableData", "selectedTable", "pagination"]);
const emits = defineEmits(["edit", "delete", "selectionChange", "updateCell"]);

// 初始化edit、selecting
const isEditing: IObj[] = reactive([]);
const isSelecting: IObj[] = reactive([]);

function initStatus() {
  const obj: IObj = {};
  const selectObj: IObj = {};

  for (const item in organizationMemberMap) {
    const val = organizationMemberMap[item];

    if (selects.includes(item)) {
      selectObj[val] = false;
    } else {
      obj[val] = false;
    }
  }

  for (const item of props.tableData) {
    const deepObj = lodash.cloneDeep(obj);
    isEditing.push(deepObj);

    const deepSelectObj = lodash.cloneDeep(selectObj);
    isSelecting.push(deepSelectObj);
  }
}

watchEffect(() => {
  const tableData = props.tableData;
  initStatus();
});

// 初始化结束

const store = useStore();

const computePosition = computed(() => {
  return function (index: number) {
    // console.log(props.tableData[index].positions);

    const positions = props.tableData[index].positions;

    let result = "";
    const getters = store.getters;

    for (const item of positions) {
      result += `${getters.organizationMap[item.organization]} `;

      result += `${item.position};\n`;
    }

    result = result.slice(0, result.length - 1);

    return result;
  };
});

// 用于切换p和input
let beforeValue = "";
const changeStatus = (index: number, attribute: any, isSelect?: boolean) => {
  if (isSelect) {
    isSelecting[index][attribute] = !isSelecting[index][attribute];
  } else {
    isEditing[index][attribute] = !isEditing[index][attribute];
  }

  if (isEditing[index][attribute] || isSelecting[index][attribute]) {
    beforeValue = props.tableData[index][attribute];
  } else {
    if (attribute.includes("Time")) {
      if (!isDateValid(props.tableData[index][attribute])) {
        props.tableData[index][attribute] = beforeValue;
        ElMessage({
          message: "格式错误，修改失败",
          type: "info",
        });
      }
    }
  }

  if (
    !isSelecting[index][attribute] &&
    !isEditing[index][attribute] &&
    props.tableData[index][attribute] !== beforeValue
  ) {
    emits("updateCell", index, attribute);
  }
};

const handleVisibleChange = (
  show: boolean,
  index: number,
  attribute: any,
  isSelect?: boolean
) => {
  if (!show) {
    changeStatus(index, attribute, isSelect);
  }
};
const handleEdit = (index: number, row: ITable) => {
  console.log(index, row);
  emits("edit", row);
};

const handleDelete = (index: number, row: ITable) => {
  console.log(index, row);
  emits("delete", row);
};

const mytableRef = ref<InstanceType<typeof ElTable>>();

const handleSelectionChange = (selection: ITable[]) => {
  // console.log(selection);
  emits("selectionChange", selection);
};

// ing
watch(
  () => props.tableData,
  () => {
    const selectedTable = [];
    for (const item in props.selectedTable) {
      if (props.selectedTable[item].length != 0) {
        selectedTable.push(...props.selectedTable[item]);
      }
    }

    for (const item of props.tableData) {
      for (const selectItem of selectedTable) {
        if (selectItem.rowId === item.rowId) {
          mytableRef.value?.toggleRowSelection(item, true);
        }
      }
    }
  },
  {
    deep: true,
  }
);

const indexMethod = (index: number) => {
  return (
    index + 1 + props.pagination.pageSize * (props.pagination.currentPage - 1)
  );
};
</script>

<style lang="less" scoped>
.table-box {
  // width: calc(100vw - 240px);
  .mytable {
    width: 100%;
    height: 59vh;
    p {
      overflow: hidden;
      text-overflow: ellipsis;
      display: -webkit-box;
      -webkit-line-clamp: 3;
      -webkit-box-orient: vertical;
    }

    .operation {
      display: flex;
      align-items: center;
      justify-content: center;

      span {
        color: #3f85ed;
        cursor: pointer;
        margin-right: 20px;
      }

      span:last-child {
        margin-right: 0;
      }

      .moveup-text,
      .movedown-text {
        color: #666;
      }

      .delete-text {
        margin-left: 20px;
      }

      .move {
        display: inline-flex;
        flex-direction: column;
        font-size: 16px;
        margin-left: 8px;
      }
    }
  }
}

:deep(.el-dialog_body) {
  height: 40vh;
  overflow: auto;
}

p {
  white-space: pre-wrap;
}
</style>
